package com.ruoyi.common.qy.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.nio.charset.StandardCharsets;

public class QwenHttpClientUtils {
    // 正确的API端点 - 非常重要！
    private static final String API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";

    private final String apiKey;
    private final CloseableHttpClient httpClient;
    private final ObjectMapper objectMapper;

    public QwenHttpClientUtils(String apiKey) {
        this.apiKey = apiKey;
        this.objectMapper = new ObjectMapper();

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(30000)
                .setSocketTimeout(60000)
                .build();

        this.httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    /**
     * 发送消息到千问API（使用qwen-plus模型）
     */
    public String sendMessage(String prompt) throws Exception {
        return sendMessage(prompt, "qwen-plus", 0.8, 1024);
    }

    /**
     * 发送消息到千问API（带参数）
     */
    public String sendMessage(String prompt, String model, double temperature, int maxTokens) throws Exception {
        // 构建请求JSON
        String requestBody = buildRequestBody(prompt, model, temperature, maxTokens);

        System.out.println("请求体: " + requestBody); // 调试信息

        HttpPost httpPost = new HttpPost(API_URL);
        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setHeader("Authorization", "Bearer " + apiKey);

        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));

        HttpResponse response = httpClient.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();

        String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        System.out.println("响应状态码: " + statusCode);
        System.out.println("响应内容: " + responseString); // 调试信息

        if (statusCode != 200) {
            throw new RuntimeException("API请求失败，状态码: " + statusCode + ", 响应: " + responseString);
        }

        return parseAndContinueIfNeeded(responseString,prompt, model, temperature, maxTokens);
    }
    /**
     * 解析响应并自动继续生成
     */
    private String parseAndContinueIfNeeded(String responseString, String originalPrompt,
                                            String model, double temperature, int maxTokens) throws Exception {
        ObjectNode responseJson = (ObjectNode) objectMapper.readTree(responseString);

        // 检查错误
        if (responseJson.has("code")) {
            String code = responseJson.get("code").asText();
            if (!code.equals("200")) {
                String message = responseJson.has("message") ?
                        responseJson.get("message").asText() : "未知错误";
                throw new RuntimeException("API错误: " + message + " (代码: " + code + ")");
            }
        }

        // 提取响应文本和完成原因
        if (responseJson.has("output")) {
            JsonNode outputNode = responseJson.get("output");

            // 获取完成原因
            String finishReason = "stop";
            if (outputNode.has("finish_reason")) {
                finishReason = outputNode.get("finish_reason").asText();
            }

            // 提取文本内容
            String currentText = outputNode.get("text").asText();

            System.out.println("完成原因: " + finishReason);
            System.out.println("当前文本长度: " + currentText.length());

            // 如果因为长度限制被截断，继续生成
            if ("length".equals(finishReason)) {
                System.out.println("检测到响应被截断，开始继续生成...");
                return continueGeneration(currentText, originalPrompt, model, temperature, maxTokens);
            }

            return currentText;
        } else {
            throw new RuntimeException("无法解析响应: " + responseString);
        }
    }

    /**
     * 继续生成剩余内容
     */
    private String continueGeneration(String currentText, String originalPrompt,
                                      String model, double temperature, int maxTokens) throws Exception {
        StringBuilder fullText = new StringBuilder(currentText);
        int continuationCount = 0;
        final int MAX_CONTINUATIONS = 3; // 最大继续生成次数

        while (continuationCount < MAX_CONTINUATIONS) {
            continuationCount++;
            System.out.println("=== 第 " + continuationCount + " 次继续生成 ===");

            // 构建继续生成的提示词
            String continuationPrompt = buildContinuationPrompt(originalPrompt, fullText.toString());

            // 发送继续生成请求
            String continuation = sendSingleMessage(continuationPrompt, model, temperature, maxTokens);

            if (continuation != null && !continuation.trim().isEmpty()) {
                fullText.append(continuation);
                System.out.println("本次继续生成内容长度: " + continuation.length());
                System.out.println("累计内容长度: " + fullText.length());

                // 检查是否还需要继续（通过判断最后一次响应是否也被截断）
                if (!wasLastResponseTruncated(continuationPrompt, model, temperature, maxTokens)) {
                    System.out.println("内容生成完成");
                    break;
                }
            } else {
                System.out.println("继续生成返回空内容，停止继续");
                break;
            }

            // 避免无限循环
            if (continuationCount >= MAX_CONTINUATIONS) {
                System.out.println("已达到最大继续生成次数 (" + MAX_CONTINUATIONS + ")");
            }

            // 添加短暂延迟
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }

        return fullText.toString();
    }

    /**
     * 单次消息发送（不包含继续逻辑）
     */
    private String sendSingleMessage(String prompt, String model, double temperature, int maxTokens) throws Exception {
        String requestBody = buildRequestBody(prompt, model, temperature, maxTokens);

        HttpPost httpPost = new HttpPost(API_URL);
        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setHeader("Authorization", "Bearer " + apiKey);
        httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));

        HttpResponse response = httpClient.execute(httpPost);
        String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);

        return parseSingleResponse(responseString);
    }

    /**
     * 解析单次响应（不包含继续逻辑）
     */
    private String parseSingleResponse(String responseString) throws Exception {
        ObjectNode responseJson = (ObjectNode) objectMapper.readTree(responseString);

        // 检查错误
        if (responseJson.has("code")) {
            String code = responseJson.get("code").asText();
            if (!code.equals("200")) {
                String message = responseJson.has("message") ?
                        responseJson.get("message").asText() : "未知错误";
                throw new RuntimeException("API错误: " + message + " (代码: " + code + ")");
            }
        }

        // 提取响应文本
        if (responseJson.has("output") && responseJson.get("output").has("text")) {
            return responseJson.get("output").get("text").asText();
        } else {
            throw new RuntimeException("无法解析响应: " + responseString);
        }
    }

    /**
     * 检查最后一次响应是否被截断
     */
    private boolean wasLastResponseTruncated(String prompt, String model, double temperature, int maxTokens) throws Exception {
        // 发送一个测试请求来检查是否还会被截断
        String testPrompt = "继续写一句话：";
        String testResponse = sendSingleMessage(testPrompt, model, temperature, 50);

        // 如果响应很短，可能被截断
        return testResponse.length() < 30;
    }
    /**
     * 构建继续生成的提示词
     */
    private String buildContinuationPrompt(String originalPrompt, String currentText) {
        // 截取最后一部分内容作为上下文（避免提示词过长）
        String recentContext = currentText;
        if (currentText.length() > 1000) {
            recentContext = currentText.substring(currentText.length() - 1000);
        }

        return String.format(
                "请继续完成以下被截断的内容。\n" +
                        "原始问题：%s\n\n" +
                        "当前已生成的内容：%s\n\n" +
                        "请接着上面的内容继续写下去，保持风格和语气一致，确保内容完整自然：",
                originalPrompt, recentContext
        );
    }

    /**
     * 构建请求体（符合千问API格式）
     */
    private String buildRequestBody(String prompt, String model, double temperature, int maxTokens) throws Exception {
        ObjectNode requestBody = objectMapper.createObjectNode();
        requestBody.put("model", model);

        // 输入参数 - 千问API的格式
        ObjectNode inputNode = objectMapper.createObjectNode();
        inputNode.put("prompt", prompt);
        requestBody.set("input", inputNode);

        // 生成参数
        ObjectNode parameters = objectMapper.createObjectNode();
        parameters.put("temperature", temperature);
//        parameters.put("max_tokens", maxTokens);
        parameters.put("top_p", 0.8);
        parameters.put("top_k", 50);
        parameters.put("repetition_penalty", 1.1);
        parameters.put("enable_search", false); // 是否启用联网搜索
        requestBody.set("parameters", parameters);

        return objectMapper.writeValueAsString(requestBody);
    }

    /**
     * 解析API响应
     */
    private String parseResponse(String responseString) throws Exception {
        ObjectNode responseJson = (ObjectNode) objectMapper.readTree(responseString);

        // 检查错误
        if (responseJson.has("code")) {
            String code = responseJson.get("code").asText();
            if (!code.equals("200")) {
                String message = responseJson.has("message") ?
                    responseJson.get("message").asText() : "未知错误";
                throw new RuntimeException("API错误: " + message + " (代码: " + code + ")");
            }
        }

        // 提取响应文本
        if (responseJson.has("output") &&
            responseJson.get("output").has("text")) {
            return responseJson.get("output").get("text").asText();
        } else {
            throw new RuntimeException("无法解析响应: " + responseString);
        }
    }

    public void close() throws Exception {
        if (httpClient != null) {
            httpClient.close();
        }
    }
}
